package cn.seaboot.admin.reverse.manager;

import cn.seaboot.admin.reverse.bean.DataColumn;
import cn.seaboot.admin.reverse.bean.DataTable;
import cn.seaboot.flake.entity.NormColumn;
import cn.seaboot.flake.entity.NormTable;
import cn.seaboot.commons.core.CommonUtils;
import cn.seaboot.commons.core.Converter;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 数据库配置信息转换为标准表配置
 *
 * 方便后续程序的进一步加工
 *
 * @author Mr.css
 * @version 2020-12-04 9:54
 */
@Service
public class DataToNormConverter {

    /**
     * 获取标准数据信息
     *
     * @param dataTable 数据库基本信息
     * @return DbNormTable
     */
    public NormTable dataTableToNormTable(DataTable dataTable) {
        NormTable table = this.converse2NormTable(dataTable);
        List<DataColumn> columns = dataTable.getColumns();
        if (columns != null) {
            table.setColumns(this.converse2NormColumns(columns));
        }
        return table;
    }


    /**
     * 获取标准数据信息
     *
     * @param dataTables 数据库基本信息
     * @return DbNormTable
     */
    public List<NormTable> dataTableToNormTable(List<DataTable> dataTables) {
        if (CommonUtils.isNotEmpty(dataTables)) {
            List<NormTable> res = new ArrayList<>(dataTables.size());
            for (DataTable dataTable : dataTables) {
                NormTable normTable = this.dataTableToNormTable(dataTable);
                res.add(normTable);
            }
            return res;
        }
        return null;
    }

    /**
     * MySQL数据 -> 标准基数据
     *
     * @param tableInfo DbDataTables
     * @return DbNormTable
     */
    private NormTable converse2NormTable(DataTable tableInfo) {
        // 表名、库名统一大写，避免因为大小写出错
        NormTable table = new NormTable();
        table.setSchemaName(tableInfo.getTableSchema());
        table.setTableName(tableInfo.getTableName());
        table.setTableComment(tableInfo.getTableComment());
        return table;
    }

    /**
     * MySQL数据 -> 标准基数据
     *
     * @param columnInfos DbDataColumns
     * @return DbNormColumn
     */
    private List<NormColumn> converse2NormColumns(List<DataColumn> columnInfos) {
        List<NormColumn> columns = new ArrayList<>();
        for (DataColumn info : columnInfos) {
            NormColumn column = converse2NormColumn(info);
            columns.add(column);
        }
        return columns;
    }

    /**
     * MySQL数据 -> 标准基数据
     *
     * @param info DbDataColumns
     * @return DbNormColumn
     */
    private NormColumn converse2NormColumn(DataColumn info) {
        NormColumn column = new NormColumn();

        // 表名、库名统一大写，避免因为大小写出错
        column.setSchemaName(info.getTableSchema());
        column.setTableName(info.getTableName());
        column.setColumnName(info.getColumnName());

        // 类型
        String jdbcType = info.getDataType();
        column.setJdbcType(jdbcType);
        column.setColumnType(info.getColumnType());

        // 字段类型判断
        if (info.getCharacterMaximumLength() != null) {
            column.setSuperType("string");
            column.setLength(info.getCharacterMaximumLength());
        } else if (info.getNumericPrecision() != null) {
            column.setSuperType("number");
            column.setNumericPrecision(Converter.toInteger(info.getNumericPrecision()));
            column.setNumericScale(Converter.toInteger(info.getNumericScale()));
        } else if ("datetime".equals(info.getDataType())){
            column.setSuperType("datetime");
        } else if ("date".equals(info.getDataType())){
            column.setSuperType("date");
        } else if ("json".equals(info.getDataType())){
            column.setSuperType("json");
        }

        // 不允许为空，切未设置默认值，说明参数必传
        column.setDefaultValue(info.getColumnDefault());
        column.setNullable(Converter.toBool(info.getIsNullable(), true));
        column.setRequire(!column.getNullable() && info.getColumnDefault() == null);

        // key
        column.setColumnKey(info.getColumnKey());

        // 排序以及注释
        column.setOrdinalPosition(Converter.toInteger(info.getOrdinalPosition()));
        column.setColumnComment(info.getColumnComment());
        return column;
    }
}
